home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / computerjanitorapp / app.py < prev    next >
Encoding:
Python Source  |  2009-04-17  |  6.5 KB  |  193 lines

  1. # app.py - the application main program of Computer Janitor
  2. # Copyright (C) 2008, 2009  Canonical, Ltd.
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, version 3 of the License.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  15.  
  16.  
  17. import ConfigParser
  18. import logging
  19. import logging.handlers
  20. import optparse
  21. import os
  22. import sys
  23.  
  24. import computerjanitor
  25. import computerjanitorapp
  26. _ = computerjanitorapp.setup_gettext()
  27.  
  28.  
  29. DEFAULT_PLUGINS_DIRS = "/usr/share/computerjanitor/plugins"
  30. DEFAULT_STATE_FILE = "/var/lib/computer-janitor/state.dat"
  31.  
  32.  
  33. class SourcesListProblem(computerjanitor.Exception):
  34.  
  35.     def __init__(self, missing_package):
  36.         self._str = _("Essential package %s is missing. There may be "
  37.                       "problems with apt sources.list or Packages files may "
  38.                       "be missing?") % missing_package
  39.  
  40.  
  41. class AsciiFormatter(logging.Formatter):
  42.  
  43.     def format(self, record): # pragma: no cover
  44.         msg = logging.Formatter.format(self, record)
  45.         return msg.encode('ascii', 'replace')
  46.  
  47.  
  48. def setup_logging(): # pragma: no cover
  49.     if os.environ.get("COMPUTER_JANITOR_DEBUG", None) == "yes":
  50.         level = logging.DEBUG
  51.     elif os.environ.get("COMPUTER_JANITOR_UNITTEST", None) == "yes":
  52.         level = logging.CRITICAL
  53.     else:
  54.         level = logging.INFO
  55.     logging.basicConfig(level=level, format="%(levelname)s: %(message)s")
  56.  
  57.     try:
  58.         formatter = AsciiFormatter(
  59.                         "computer-janitor %(levelname)s: %(message)s")
  60.         handler = logging.handlers.SysLogHandler("/dev/log")
  61.         handler.setLevel(level)
  62.         handler.setFormatter(formatter)
  63.         logging.getLogger().addHandler(handler)
  64.     except:
  65.         # We're OK with something going wrong.
  66.         logging.debug(_("Logging to syslog cannot be set up."))
  67.  
  68.  
  69. class Application(object):
  70.  
  71.     """The main class for the program."""
  72.  
  73.     whitelist_dirs = ["/etc/computer-janitor.d"]
  74.  
  75.     def __init__(self, apt=None):
  76.         self.state = computerjanitorapp.State()
  77.         self.parser = self.create_option_parser()
  78.         self.apt = computerjanitor.apt
  79.         if apt is not None:
  80.             self.apt = apt
  81.         self.refresh_apt_cache()
  82.         
  83.         # The Plugin API requires that we have a config that is a
  84.         # ConfigParser. We don't use it for anything, for now.
  85.         self.config = ConfigParser.ConfigParser()
  86.         
  87.     def run(self, ui_class, 
  88.             plugin_manager_class=computerjanitor.PluginManager):
  89.         setup_logging()
  90.         logging.debug(_("Running application, with:"))
  91.         logging.debug("  plugin_manager_class=%s" % plugin_manager_class)
  92.         
  93.         options, args = self.parse_options()
  94.  
  95.         pluginpath = os.environ.get("COMPUTER_JANITOR_PLUGINS", 
  96.                                     DEFAULT_PLUGINS_DIRS)
  97.         plugindirs = pluginpath.split(":")
  98.         pm = plugin_manager_class(self, plugindirs)
  99.  
  100.         ui = ui_class(self, pm)
  101.         ui.run(options, args)
  102.  
  103.     def create_option_parser(self): # pragma: no cover
  104.         parser = optparse.OptionParser(version="%%prog %s" % 
  105.                                         computerjanitorapp.VERSION)
  106.         
  107.         parser.usage = _("""
  108. %prog [options] find
  109. %prog [options] cleanup [CRUFT]...
  110. %prog [options] ignore [CRUFT]...
  111. %prog [options] unignore [CRUFT]...
  112.  
  113. %prog finds and removes cruft from your system. 
  114.  
  115. Cruft is anything that shouldn't be on the system, but is. Stretching
  116. the definition, it is also things that should be on the system, but
  117. aren't.""")
  118.  
  119.         parser.add_option("--all", action="store_true",
  120.                           help=_("Make the 'cleanup' command remove all "
  121.                                  "packages, if none are given on the "
  122.                                  "command line."))
  123.  
  124.         parser.add_option("--state-file", metavar="FILE",
  125.                           default=DEFAULT_STATE_FILE,
  126.                           help=_("Store state of each piece of cruft in "
  127.                                  "FILE. (Default is %default)."))
  128.  
  129.         parser.add_option("--no-act", action="store_true",
  130.                           help=_("Don't actually remove anything, just "
  131.                                  "pretend to do so. This is useful for "
  132.                  "testing stuff."))
  133.  
  134.         parser.add_option("--verbose", action="store_true",
  135.                           help=_("Verbose operation: make find show an "
  136.                                  "explanation for each piece of cruft "
  137.                  "found."))
  138.  
  139.         return parser
  140.  
  141.     def parse_options(self, args=None):
  142.         return self.parser.parse_args(args=args)
  143.  
  144.     def refresh_apt_cache(self):
  145.         self.apt_cache = self.apt.Cache()
  146.     self.apt_cache._depcache.ReadPinFile("/var/lib/synaptic/preferences")
  147.  
  148.     def verify_apt_cache(self):
  149.         for name in ["dash", "gzip"]:
  150.             if name not in self.apt_cache:
  151.                 raise SourcesListProblem(name)
  152.             if not self.apt_cache[name].candidateDownloadable:
  153.                 raise SourcesListProblem(name)
  154.  
  155.     def whitelist_files(self, dirnames):
  156.         """Find files with whitelists in a list of directories.
  157.  
  158.         The directory is scanned for files ending in ".whitelist".
  159.         Subdirectories are not scanned.
  160.  
  161.         """
  162.  
  163.         list = []
  164.         for dirname in dirnames:
  165.             try:
  166.                 basenames = os.listdir(dirname)
  167.                 whitelists = [x for x in basenames if x.endswith(".whitelist")]
  168.                 list += [os.path.join(dirname, x) for x in whitelists]
  169.             except os.error:
  170.                 pass
  171.  
  172.         return list
  173.  
  174.     def whitelisted_cruft(self, dirnames=None):
  175.         """Return list of cruft that is whitelisted."""
  176.  
  177.         dirnames = dirnames or self.whitelist_dirs
  178.  
  179.         list = []
  180.         for filename in self.whitelist_files(dirnames):
  181.             f = file(filename, "r")
  182.             for line in f.readlines():
  183.                 line = line.strip()
  184.                 if line and not line.startswith("#"):
  185.                     list.append(line)
  186.             f.close()
  187.  
  188.         return list
  189.  
  190.     def remove_whitelisted(self, crufts, dirnames=None):
  191.         whitelisted = self.whitelisted_cruft(dirnames=dirnames)
  192.         return [c for c in crufts if c.get_name() not in whitelisted]
  193.